home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / datatypes / binarydt / source / dispatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-07  |  32.6 KB  |  1,335 lines

  1. /*
  2. ** $PROJECT: binary.datatype
  3. **
  4. ** $VER: dispatch.c 39.11 (11.04.95)
  5. **
  6. ** by
  7. **
  8. ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
  9. **
  10. ** (C) Copyright 1994,1995
  11. ** All Rights Reserved !
  12. **
  13. ** $HISTORY:
  14. **
  15. ** 11.04.95 : 039.011 : new DTBM_#? methods,DTM_TRIGGER and DTM_DRAW methods
  16. ** 19.02.95 : 039.010 : fixed bug,which caused a crash ,if the display width was
  17. **                      less than the required width for the offsets.
  18. **                      prefs file parsing now via ReadArgs().
  19. **                      new prefs directory : 'Env:DataTypes' .
  20. ** 28.01.95 : 039.009 : fixed down scrolling bug, which skipped one line
  21. ** 22.01.95 : 039.008 : now supports DTM_PRINT method and searchs for PROGDIR:binary.prefs
  22. ** 21.01.95 : 039.007 : bug fixed. Rendering address higher than the file length (small files)
  23. ** 28.12.94 : 039.006 : now it's a base datatype and no async layout is needed
  24. ** 24.11.94 : 039.005 : memory handling improved, layout only performed if needed
  25. ** 18.11.94 : 039.004 : added PREFS file
  26. ** 16.11.94 : 039.003 : BDTDH_NONE now works
  27. ** 15.11.94 : 039.002 : added BDTA_BytesPerLine,BDTA_DisplayHex and BDTA_ShowASCII attrs
  28. ** 13.11.94 : 039.001 : initial
  29. */
  30.  
  31. /* ------------------------------- include -------------------------------- */
  32.  
  33. #include "classbase.h"
  34.  
  35. /* ------------------------------- autodoc -------------------------------- */
  36.  
  37. /*FS*/ /*"AutoDoc"*/
  38. /*GB*** binary.datatype/binary.datatype **************************************
  39. *
  40. *    NAME
  41. *        binary.datatype -- data type for any binary file
  42. *
  43. *    FUNCTION
  44. *        The binary data type, a base-class of all binary data, is used to
  45. *        load any binary file and displays the contents of the file in hex
  46. *        format.
  47. *
  48. *    PREFS
  49. *        The data type tries to load the prefs file first from
  50. *        "PROGDIR:Prefs/DataTypes/binary.prefs" and then
  51. *        "ENV:DataTypes/binary.prefs" on each OM_NEW method to set up the
  52. *        attributes !
  53. *        Up from version 39.10 it uses the ReadArgs() function to parse the
  54. *        prefs file. The template is :
  55. *
  56. *        NOASCII/S,NOWRAP/S,NONE/S,BYTE/S,WORD/S,LONG/S,BPL=BYTESPERLINE/N/K
  57. *
  58. *        NOASCII   - sets BDTA_ShowASCII to FALSE
  59. *        NOWRAP    - sets BDTA_DisplayWrap to FALSE
  60. *        NONE      - sets BDTA_DisplayHex to BDTDH_NONE
  61. *        BYTE      - sets BDTA_DisplayHex to BDTDH_BYTE
  62. *        WORD      - sets BDTA_DisplayHex to BDTDH_WORD
  63. *        LONG      - sets BDTA_DisplayHex to BDTDH_LONG
  64. *        BYTESPERLINE <bpl> or
  65. *        BPL <bpl> - sets BDTA_BytesPerLine to <bpl> bytes
  66. *
  67. *        The options can be on several lines !
  68. *
  69. *    METHODS
  70. *        OM_NEW -- Create a new text object from a binary file in hex mode.
  71. *
  72. *        OM_DISPOSE -- dispose a object
  73. *
  74. *        OM_GET -- get a attribute of the object
  75. *
  76. *        OM_SET -- set attributes of the object
  77. *
  78. *        OM_UPDATE -- update some attributes of the object
  79. *
  80. *        GM_LAYOUT -- Method to layout the hex text
  81. *
  82. *        GM_RENDER -- draw the object
  83. *
  84. *        DTM_WRITE -- DTWM_RAW mode is supported
  85. *
  86. *        DTM_PRINT -- prints the hex text
  87. *
  88. *        DTM_DRAW -- draws the datatype in the given RastPort (This is
  89. *            expermintal, I use this method for my new text.datatype to
  90. *            embed other datatype objects ! Don't use this at the moment !)
  91. *
  92. *        DTM_TRIGGER -- trigger methods to let the user input a search string
  93. *            and to search next or previous occurence of that string :
  94. *            STM_ACTIVATE_FIELD (return) - opens the string requester. This
  95. *                requester is spawned asyncronly !
  96. *            STM_BROWSE_NEXT ('>') - searchs next occurence
  97. *            STM_BROWSE_PREV ('<') - searchs previous occurence
  98. *
  99. *        DTBM_GETSTRING -- opens a requester to let the user input the
  100. *            string !
  101. *
  102. *        DTBM_SEARCHNEXT -- searchs for the next occurence of the specified
  103. *            string
  104. *
  105. *        DTBM_SEARCHPREV -- searchs for the previous occurance of the given
  106. *            string
  107. *
  108. *    TAGS
  109. *        BDTA_Buffer -- (UBYTE *) pointer to the buffer, which should be
  110. *            displayed.
  111. *            Applicability is (ISG).
  112. *
  113. *        BDTA_BufferLen -- (ULONG) length of the buffer supplied with
  114. *            BDTA_Buffer tag. This must be given if the buffer tag is
  115. *            specified.
  116. *            Applicability is (ISG).
  117. *
  118. *        BDTA_BytesPerLine -- (UWORD) number of bytes per line.
  119. *            If BDTA_DisplayHex is BDTDH_WORD it must be a multiply of 2,
  120. *            if it is BDTDH_LONG it must be a multiply of 4 !
  121. *            Default is 32.
  122. *            Applicability is (ISGNU).
  123. *
  124. *        BDTA_DisplayHex -- (UWORD) type of the display. The following types
  125. *            are supported : BDTDH_NONE  - displays no hex values
  126. *                            BDTDH_BYTE  - displays each byte in hex ( 8 bit)
  127. *                            BDTDH_WORD  - displays each word in hex (16 bit)
  128. *                            BDTDH_LONG  - displays each long in hex (32 bit)
  129. *            Default is BDTDH_LONG.
  130. *            Applicability is (ISGNU).
  131. *
  132. *        BDTA_ShowASCII -- (BOOL) display at the end of the line the
  133. *            appropriate ASCII string !
  134. *            Default is TRUE.
  135. *            Applicability is (ISGNU).
  136. *
  137. *        BDTA_DisplayWrap -- (BOOL) the BDTA_BytesPerLine are ignored and the
  138. *            byte number is retrieved from the object width !
  139. *            Default is TRUE.
  140. *            Applicability is (ISGNU).
  141. *
  142. *        BDTA_Found -- (STRPTR) pointer to the buffer to highlight the line.
  143. *            This is used to display the line of a found string !
  144. *            Default is NULL
  145. *            Applicability is (ISNU).
  146. *
  147. *    BUGS
  148. *        At the moment proportional fonts can't be handled.
  149. *
  150. *    SEE ALSO
  151. *        datatypesclass (where ?)
  152. *
  153. ******************************************************************************
  154. *
  155. */
  156. /*FE*/
  157.  
  158. /* ------------------------------- defines -------------------------------- */
  159.  
  160. #define G(o)               ((struct Gadget *) (o))
  161. #define GPR(msg)           ((struct gpRender *) (msg))
  162. #define SET(msg)           ((struct opSet *) (msg))
  163. #define WRMSG(msg)         ((struct dtWrite *) (msg))
  164. #define DRMSG(msg)         ((struct dtDraw *) (msg))
  165. #define FRBOX(msg)         ((struct dtFrameBox *) (msg))
  166. #define TRG(msg)           ((struct dtTrigger *) (msg))
  167. #define SMSG(msg)          ((struct dtbSearch *) (msg))
  168. #define GSMSG(msg)         ((struct dtbGetString *) (msg))
  169.  
  170. #define prefstemplate      "NOASCII/S,NOWRAP/S,NONE/S,BYTE/S,WORD/S,LONG/S,BPL=BYTESPERLINE/N/K"
  171.  
  172. enum
  173. {
  174.     PREFSARG_NOASCII,
  175.     PREFSARG_NOWRAP,
  176.     PREFSARG_NONE,
  177.     PREFSARG_BYTE,
  178.     PREFSARG_WORD,
  179.     PREFSARG_LONG,
  180.     PREFSARG_BYTESPERLINE,
  181.     PREFSARG_MAX
  182. };
  183.  
  184. /* ---------------------------- instance data ----------------------------- */
  185.  
  186. struct BinaryData
  187. {
  188.     UBYTE *bd_Buffer;
  189.     UBYTE *bd_BufferEnd;
  190.     ULONG bd_BufferLen;
  191.  
  192.     UWORD bd_Flags;
  193.     UWORD bd_DisplayHex;
  194.     UWORD bd_BytesPerLine;
  195.  
  196.     UWORD bd_NumGroups;
  197.     UWORD bd_LineBytes;
  198.  
  199.     UWORD bd_LineBufferLen;
  200.     UBYTE *bd_LineBuffer;
  201.  
  202.     ULONG bd_OldX;
  203.     ULONG bd_OldY;
  204.  
  205.     /* font support */
  206.     struct TextFont *bd_Font;
  207.     struct TextAttr bd_TextAttr;
  208.     UBYTE bd_FontName[MAXFONTNAME];
  209.  
  210.     UBYTE bd_Name[256];
  211.  
  212.     UBYTE bd_InputString[80];
  213.     UBYTE bd_SearchString[80];
  214.  
  215.     STRPTR bd_Found;
  216.  
  217.     struct dtbGetString bd_GetStringMsg;
  218. };
  219.  
  220. #define BDF_SHOWASCII         (1<<0)
  221. #define BDF_ALLOCATED         (1<<1)
  222. #define BDF_DISPLAYWRAP       (1<<2)
  223. #define BDF_NEEDLAYOUT        (1<<3)
  224. #define BDF_NEEDRENDERING     (1<<4)
  225.  
  226. /* ---------------------------- constant data ----------------------------- */
  227.  
  228. const ULONG methods[] = {
  229.     OM_NEW,
  230.     OM_DISPOSE,
  231.     OM_GET,
  232.     OM_SET,
  233.     OM_UPDATE,
  234.     GM_LAYOUT,
  235.     GM_RENDER,
  236.     DTM_WRITE,
  237.     DTM_PRINT,
  238.     DTM_DRAW,
  239.     DTM_FRAMEBOX,
  240.     ~0};
  241.  
  242. /* ------------------------------ init class ------------------------------ */
  243.  
  244. /*FS*/ LibCall Class *initClass(REGA6 struct ClassBase *cb)
  245. {
  246.     Class *cl;
  247.  
  248.     D(bug("init binary.datatype !\n"));
  249.  
  250.     if((cl = MakeClass("binary.datatype","datatypesclass",NULL,sizeof(struct BinaryData),0)))
  251.     {
  252.         cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
  253.         cl->cl_UserData = (ULONG) cb;
  254.  
  255.         AddClass(cl);
  256.     }
  257.  
  258.     return(cl);
  259. }
  260. /*FE*/
  261.  
  262. /* -------------------------- support functions --------------------------- */
  263.  
  264. /*FS*/ BOOL readPrefs(struct ClassBase *cb,struct BinaryData *bd,STRPTR file)
  265. {
  266.     struct RDArgs *rdargs;
  267.     struct RDArgs *args;
  268.     BPTR fh;
  269.  
  270.     ENTERING;
  271.  
  272.     if((fh = Open(file,MODE_OLDFILE)))
  273.     {
  274.         UBYTE buf[256];
  275.         ULONG para[PREFSARG_MAX];
  276.         LONG i;
  277.  
  278.         DB(("def file %s opened\n",file));
  279.  
  280.         while(FGets(fh,buf,sizeof(buf)))
  281.         {
  282.             DB(("line : %s",buf));
  283.  
  284.             if((rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL)))
  285.             {
  286.                 rdargs->RDA_Source.CS_Buffer   = buf;
  287.                 rdargs->RDA_Source.CS_Length   = strlen(buf);
  288.  
  289.                 for(i=0 ; i < (sizeof(para)/sizeof(LONG)) ; i++)
  290.                     para[i]=0;
  291.  
  292.                 DB(("rdargs at : %lx\n",rdargs));
  293.                 
  294.                 if((args = ReadArgs(prefstemplate,(LONG *) para,rdargs)))
  295.                 {
  296.                     DB(("args at %lx\n",args));
  297.  
  298.                     if(para[PREFSARG_NOASCII])
  299.                         bd->bd_Flags &= ~BDF_SHOWASCII;
  300.  
  301.                     if(para[PREFSARG_NOWRAP])
  302.                         bd->bd_Flags &= ~BDF_DISPLAYWRAP;
  303.  
  304.                     if(para[PREFSARG_NONE])
  305.                         bd->bd_DisplayHex = BDTDH_NONE;
  306.  
  307.                     if(para[PREFSARG_BYTE])
  308.                         bd->bd_DisplayHex = BDTDH_BYTE;
  309.  
  310.                     if(para[PREFSARG_WORD])
  311.                         bd->bd_DisplayHex = BDTDH_WORD;
  312.  
  313.                     if(para[PREFSARG_LONG])
  314.                         bd->bd_DisplayHex = BDTDH_LONG;
  315.  
  316.                     if(para[PREFSARG_BYTESPERLINE])
  317.                     {
  318.                         bd->bd_BytesPerLine = (UWORD) *((LONG *) para[PREFSARG_BYTESPERLINE]);
  319.  
  320.                         if(bd->bd_BytesPerLine < 4)
  321.                             bd->bd_BytesPerLine = 4;
  322.                         if(bd->bd_BytesPerLine > (1<<16))
  323.                             bd->bd_BytesPerLine = 32;
  324.                     }
  325.                 }
  326.                 FreeDosObject(DOS_RDARGS , rdargs);
  327.             }
  328.         }
  329.         Close(fh);
  330.     }
  331.  
  332.     LEAVING;
  333.  
  334.     return((BOOL) (fh == NULL));
  335. }
  336. /*FE*/
  337.  
  338. /*FS*/ void useDefaultFont(struct ClassBase *cb,struct BinaryData *bd)
  339. {
  340.     struct TextFont *deffont;
  341.  
  342.     D(bug("using default font !\n"));
  343.  
  344.     #undef GfxBase
  345.     deffont = ((struct GfxBase *) cb->cb_GfxBase)->DefaultFont;
  346.     #define GfxBase cb->cb_GfxBase
  347.  
  348.     bd->bd_TextAttr.ta_YSize = deffont->tf_YSize;
  349.     bd->bd_TextAttr.ta_Style = FS_NORMAL;
  350.     bd->bd_TextAttr.ta_Flags = deffont->tf_Flags;
  351.     bd->bd_TextAttr.ta_Name  = bd->bd_FontName;
  352.     strcpy(bd->bd_TextAttr.ta_Name,deffont->tf_Message.mn_Node.ln_Name);
  353.  
  354.     bd->bd_Font = OpenFont(&bd->bd_TextAttr);
  355. }
  356. /*FE*/
  357.  
  358. /* --------------------------- class dispatcher --------------------------- */
  359.  
  360. /*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
  361. {
  362.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  363.     struct BinaryData *bd = INST_DATA(cl,obj);
  364.     ULONG retval = 0;
  365.  
  366.     switch(msg->MethodID)
  367.     {
  368.     case OM_NEW:
  369.         {
  370.             Object *newobj;
  371.             if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
  372.             {
  373.                 bd = INST_DATA(cl,newobj);
  374.  
  375.                 /* set default setting */
  376.                 bd->bd_BytesPerLine = 32;
  377.                 bd->bd_DisplayHex   = BDTDH_LONG;
  378.                 bd->bd_Flags        = BDF_SHOWASCII | BDF_DISPLAYWRAP;
  379.  
  380.                 /* read default user settings */
  381.                 if(readPrefs(cb,bd,"PROGDIR:Prefs/DataTypes/binary.prefs"))
  382.                     readPrefs(cb,bd,"ENV:DataTypes/binary.prefs");
  383.  
  384.                 setattrs(cl,newobj,(struct opSet *) msg);
  385.  
  386.                 /* use default textfont */
  387.                 if(!bd->bd_Font)
  388.                     useDefaultFont(cb,bd);
  389.  
  390.                 /* if no buffer is provided , get the handle from the superclass
  391.                     and load the file in the buffer */
  392.                 if(!bd->bd_Buffer)
  393.                 {
  394.                     BPTR fh;
  395.                     ULONG type;
  396.                     LONG num;
  397.  
  398.                     if(((num = GetDTAttrs((Object *) newobj,DTA_Handle     ,&fh,
  399.                                                                          DTA_SourceType ,&type,
  400.                                                                          TAG_DONE)) == 2) && fh)
  401.                     {
  402.                         struct FileInfoBlock *fib;
  403.  
  404.                         D(bug("type : %ld\n",type));
  405.  
  406.                         switch(type)
  407.                         {
  408.                         case DTST_FILE:
  409.                             if((fib = AllocDosObject(DOS_FIB,NULL)))
  410.                             {
  411.                                 if(ExamineFH(fh,fib) && fib->fib_Size > 0)
  412.                                 {
  413.                                     if((bd->bd_Buffer = AllocMem(fib->fib_Size,MEMF_ANY)))
  414.                                     {
  415.                                         bd->bd_Flags |= BDF_ALLOCATED;
  416.                                         bd->bd_BufferLen = fib->fib_Size;
  417.                                         bd->bd_BufferEnd = &bd->bd_Buffer[fib->fib_Size];
  418.                                         Seek(fh,0,OFFSET_BEGINNING);
  419.                                         Read(fh,bd->bd_Buffer,bd->bd_BufferLen);
  420.                                     }
  421.                                 }
  422.                             }
  423.                             FreeDosObject(DOS_FIB,fib);
  424.                             if(!NameFromFH(fh,bd->bd_Name,sizeof(bd->bd_Name)))
  425.                                 strcpy(bd->bd_Name,"unknown");
  426.                             break;
  427.                         case DTST_RAM:
  428.                             strcpy(bd->bd_Name,"RAM");
  429.                             break;
  430.                         default:
  431.                             D(bug("not supported SourceType : %ld\n",type));
  432.                         }
  433.  
  434.                     }
  435.                 }
  436.  
  437.                 if(bd->bd_Buffer)
  438.                 {
  439.                     retval = (ULONG) newobj;
  440.                     setSuperAttrs(cl,newobj,NULL,GA_RelSpecial,TRUE,TAG_DONE);
  441.                     ((struct ExtGadget *) newobj)->MoreFlags = GMORE_SCROLLRASTER;
  442.                 } else  /* something was going wrong, thus dispose myself */
  443.                 {
  444.                     D(bug("binary.datatype error : %ld\n",IoErr()));
  445.                     CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
  446.                 }
  447.             }
  448.         }
  449.         break;
  450.     case OM_DISPOSE:
  451.         if(bd->bd_Buffer && (bd->bd_Flags & BDF_ALLOCATED))
  452.             FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
  453.  
  454.         if(bd->bd_LineBuffer && bd->bd_LineBufferLen)
  455.             FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
  456.  
  457.         if(bd->bd_Font)
  458.             CloseFont(bd->bd_Font);
  459.  
  460.         retval = DoSuperMethodA(cl,obj,msg);
  461.         break;
  462.     case OM_UPDATE:
  463.     case OM_SET:
  464.         if((retval = setattrs(cl,obj,(struct opSet *) msg)))
  465.             if(bd->bd_Flags & BDF_NEEDLAYOUT)
  466.             {
  467.                 DoMethod(obj,GM_LAYOUT,((struct opSet *) msg)->ops_GInfo,TRUE);
  468.                 bd->bd_Flags &= ~BDF_NEEDLAYOUT;
  469.             }
  470.  
  471.         /* Pass the attributes to the super class and force a refresh
  472.          * if we need it */
  473.         if((retval += DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
  474.         {
  475.             struct RastPort *rp;
  476.  
  477.             /* Get a pointer to the rastport */
  478.             if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
  479.             {
  480.                 DB(("update calls GM_RENDER\n"));
  481.  
  482.                 /* Force a redraw */
  483.                 DoMethod(obj,GM_RENDER,((struct opSet *) msg)->ops_GInfo,rp,GREDRAW_REDRAW);
  484.  
  485.                 /* Release the temporary rastport */
  486.                 ReleaseGIRPort (rp);
  487.             }
  488.  
  489.             if(msg->MethodID == OM_UPDATE)
  490.                 DoMethod(obj,OM_NOTIFY,SET(msg)->ops_AttrList,SET(msg)->ops_GInfo,0);
  491.  
  492.             retval = 0;
  493.         }
  494.         break;
  495.     case OM_GET:
  496.         if(!(retval = getattr(cl,obj,(struct opGet *) msg)))
  497.             retval = DoSuperMethodA(cl,obj,msg);
  498.         break;
  499.     case GM_LAYOUT:
  500.         /* Tell everyone that we are busy doing things */
  501.         notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
  502.                                  GA_ID,       G(obj)->GadgetID,
  503.                                  DTA_Busy,    TRUE,
  504.                                  TAG_DONE);
  505.  
  506.         /* Let the super-class partake */
  507.         retval = DoSuperMethodA (cl, obj, msg);
  508.  
  509.         retval += layout(cb, cl, obj, (struct gpLayout *) msg);
  510.  
  511.         break;
  512.     case GM_RENDER:
  513.         {
  514.             struct RastPort *rp = GPR(msg)->gpr_RPort;
  515.             struct Rectangle rect;
  516.             struct IBox *domain;
  517.             ULONG x,y;
  518.             ULONG ux,uy;
  519.             ULONG py,px;
  520.             LONG topy,topx,num;
  521.             LONG w,h;
  522.             LONG dx,dy,height;
  523.             LONG chrs;
  524.  
  525.             STRPTR ptr,old;
  526.  
  527.             UBYTE fgpen = 1;
  528.             UBYTE bgpen = 0;
  529.  
  530.             D(bug("draw mode : %lx\n",GPR(msg)->gpr_Redraw));
  531.  
  532.             if(GetDTAttrs(obj,DTA_TopVert     ,&y,
  533.                                     DTA_TopHoriz    ,&x,
  534.                                     DTA_VisibleVert ,&h,
  535.                                     DTA_VisibleHoriz,&w,
  536.                                     DTA_VertUnit    ,&uy,
  537.                                     DTA_HorizUnit   ,&ux,
  538.                                     DTA_Domain      ,&domain,
  539.                                     TAG_DONE) == 7)
  540.             {
  541.                 topy = y;
  542.                 topx = x;
  543.  
  544.                 height = (h-1) * uy;
  545.  
  546.                 rect.MinX = domain->Left;
  547.                 rect.MinY = domain->Top;
  548.                 rect.MaxX = domain->Left + w * ux - 1;
  549.                 rect.MaxY = domain->Top  + h * uy - 1;
  550.  
  551.                 SetFont(GPR(msg)->gpr_RPort,bd->bd_Font);
  552.                 SetABPenDrMd(rp,fgpen,bgpen,JAM2);
  553.  
  554.                 y *= uy;
  555.                 x *= ux;
  556.  
  557.                 dx = (x - bd->bd_OldX);
  558.                 dy = (y - bd->bd_OldY);
  559.  
  560.                 bd->bd_OldX = x;
  561.                 bd->bd_OldY = y;
  562.  
  563.                 if(dx > domain->Width/2 || dx <-domain->Width/2 || bd->bd_Found)
  564.                     dx = 0;
  565.  
  566.                 if(dy > height/2 || dy < -height/2 || bd->bd_Found)
  567.                     dy = 0;
  568.  
  569.                 py = 0;
  570.                 px = 0;
  571.  
  572.                 if(dx || dy)
  573.                     ScrollRasterBF(rp,dx,dy,
  574.                                         rect.MinX,rect.MinY,rect.MaxX,rect.MaxY);
  575.  
  576.                 D(bug("dx : %ld , dy : %ld\n",dx,dy));
  577.  
  578.                 if(dx == 0)
  579.                 {
  580.                     if(dy < 0)
  581.                         height = -dy;
  582.                     else if(dy > 0)
  583.                     {
  584.                         py = height - dy;
  585.                         topy += ((domain->Height / uy) - dy/uy) - 1;
  586.                     }
  587.                 } else if(dx > 0)
  588.                 {
  589.                     px = w * ux - dx;
  590.                     topx += (w - (dx/ux));
  591.                     w = dx/ux;
  592.                 } else
  593.                 {
  594.                     w = (-dx/ux);
  595.                 }
  596.  
  597.                 num = topy * bd->bd_BytesPerLine;
  598.                 ptr = &bd->bd_Buffer[num];
  599.  
  600.                 D(bug("py : %ld , height : %ld , topy : %ld\n",py,height,topy));
  601.  
  602.                 for(; py <= height && ptr < bd->bd_BufferEnd ; py += rp->TxHeight)
  603.                 {
  604.                     if(SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  605.                         break;
  606.  
  607.                     old = ptr;
  608.  
  609.                     if((chrs = formatline(bd,&ptr,bd->bd_LineBuffer,num) - topx) > w)
  610.                         chrs = w;
  611.  
  612.                     if(chrs > 0)
  613.                     {
  614.                         Move(rp,domain->Left + px,domain->Top + py + rp->TxBaseline);
  615.                         Text(rp,&bd->bd_LineBuffer[topx],chrs);
  616.  
  617.                         if(bd->bd_Found >= old && bd->bd_Found <= ptr)
  618.                         {
  619.                             SetDrMd(rp,COMPLEMENT);
  620.                             RectFill(rp,domain->Left + px,domain->Top + py,domain->Left + px + TextLength(rp,&bd->bd_LineBuffer[topx],chrs) - 1,domain->Top + py + rp->TxHeight - 1);
  621.                             SetDrMd(rp,JAM2);
  622.                         }
  623.                     }
  624.  
  625.                     num += bd->bd_BytesPerLine;
  626.                 }
  627.                 DB(("after rendering !\n"));
  628.             }
  629.         }
  630.         break;
  631.     case DTM_WRITE:
  632.         switch(WRMSG(msg)->dtw_Mode)
  633.         {
  634.         case DTWM_RAW:
  635.             D(bug("dtWrite Rawmode : filehandle %lx !\n",WRMSG(msg)->dtw_FileHandle));
  636.             D(bug("attrs at : %lx\n",WRMSG(msg)->dtw_AttrList));
  637.             D({
  638.                     struct TagItem *tstate = WRMSG(msg)->dtw_AttrList;
  639.                     struct TagItem *tag;
  640.  
  641.                     while((tag = NextTagItem(&tstate)))
  642.                         bug("{%08lx,%ld}\n",tag->ti_Tag,tag->ti_Data);
  643.               });
  644.  
  645.             Write(WRMSG(msg)->dtw_FileHandle,bd->bd_Buffer,bd->bd_BufferLen);
  646.             retval = 1;
  647.             break;
  648.         default:
  649.             retval = DoSuperMethodA(cl,obj,msg);
  650.         }
  651.         break;
  652.     case DTM_PRINT:
  653.         {
  654.             union printerIO *pio = ((struct dtPrint *) msg)->dtp_PIO;
  655.             STRPTR ptr;
  656.             STRPTR buf;
  657.             LONG len;
  658.             ULONG num = 0;
  659.  
  660.             ptr = &bd->bd_Buffer[0];
  661.  
  662.             if((buf = AllocVec(bd->bd_LineBufferLen,MEMF_ANY)))
  663.             {
  664.                 pio->ios.io_Command = CMD_WRITE;
  665.                 pio->ios.io_Data    = buf;
  666.  
  667.                 while(ptr < bd->bd_BufferEnd && pio->ios.io_Error  == 0)
  668.                 {
  669.                     len = formatline(bd,&ptr,buf,num);
  670.  
  671.                     if(len > 0)
  672.                     {
  673.                         buf[len] = '\n';
  674.                         pio->ios.io_Length = len + 1;
  675.                         DoIO((struct IORequest *) &pio->ios);
  676.                     }
  677.                     num += bd->bd_BytesPerLine;
  678.                 }
  679.                 FreeVec(buf);
  680.             }
  681.         }
  682.         break;
  683.     /* this method is experimental ! My new text.datatype (should) support of
  684.      * embedding any datatype, which implements this DTM_DRAW method ! Don't
  685.      * use this at the moment!
  686.      */
  687.     case DTM_DRAW:
  688.         {
  689.             struct RastPort *rp = DRMSG(msg)->dtd_RPort;
  690.             STRPTR ptr;
  691.             ULONG py;
  692.             LONG topy,topx;
  693.             LONG w,h;
  694.             LONG height,num;
  695.             LONG chrs;
  696.  
  697.             topy = DRMSG(msg)->dtd_TopVert;
  698.             topx = DRMSG(msg)->dtd_TopHoriz;
  699.             height = DRMSG(msg)->dtd_Height;
  700.  
  701.             w = DRMSG(msg)->dtd_Width  / rp->TxWidth;
  702.             h = DRMSG(msg)->dtd_Height / rp->TxHeight;
  703.  
  704.             num = topy * bd->bd_BytesPerLine;
  705.             ptr = &bd->bd_Buffer[num];
  706.  
  707.             for(py = 0; py < height && ptr < bd->bd_BufferEnd ; py += rp->TxHeight)
  708.             {
  709.                 if((chrs = formatline(bd,&ptr,bd->bd_LineBuffer,num) - topx) > w)
  710.                     chrs = w;
  711.  
  712.                 if(chrs > 0)
  713.                 {
  714.                     Move(rp,DRMSG(msg)->dtd_Left,DRMSG(msg)->dtd_Top + py + rp->TxBaseline);
  715.                     Text(rp,&bd->bd_LineBuffer[topx],chrs);
  716.                 }
  717.  
  718.                 num += bd->bd_BytesPerLine;
  719.             }
  720.         }
  721.         retval = 1;
  722.         break;
  723.     case DTM_FRAMEBOX:
  724.         {
  725.             ULONG ux,uy;
  726.             ULONG w,h;
  727.             retval = 0;
  728.  
  729.             if(GetDTAttrs(obj,DTA_TotalVert   ,&h,
  730.                                     DTA_TotalHoriz  ,&w,
  731.                                     DTA_VertUnit    ,&uy,
  732.                                     DTA_HorizUnit   ,&ux,
  733.                                     TAG_DONE) == 4)
  734.             {
  735.                 if(FRBOX(msg)->dtf_FrameInfo)
  736.                 {
  737.                     FRBOX(msg)->dtf_FrameInfo->fri_Dimensions.Height = h * uy;
  738.                     FRBOX(msg)->dtf_FrameInfo->fri_Dimensions.Width  = w * ux;
  739.                     FRBOX(msg)->dtf_FrameInfo->fri_Dimensions.Depth  = 1;
  740.                     FRBOX(msg)->dtf_FrameInfo->fri_Flags             = FIF_SCROLLABLE;
  741.                     retval = 1;
  742.                 }
  743.             }
  744.         }
  745.         break;
  746.  
  747.     /* trigger interface for the search string requester , this must be asyncron ! */
  748.     case DTM_TRIGGER:
  749.         {
  750.             ULONG searchmethod = DTBM_SEARCHNEXT;
  751.             D(bug("trigger method : %ld,GInfo 0x%lx\n",TRG(msg)->dtt_Function,TRG(msg)->dtt_GInfo));
  752.  
  753.             switch(TRG(msg)->dtt_Function)
  754.             {
  755.             case STM_BROWSE_PREV:
  756.                 searchmethod = DTBM_SEARCHPREV;
  757.             case STM_BROWSE_NEXT:
  758.                 if(bd->bd_InputString[0])
  759.                 {
  760.                     DoMethod(obj,searchmethod,TRG(msg)->dtt_GInfo,bd->bd_SearchString,strlen(bd->bd_SearchString));
  761.                     break;
  762.                 }
  763.             case STM_ACTIVATE_FIELD:
  764.                 bd->bd_GetStringMsg.MethodID           = DTBM_GETSTRING;
  765.                 bd->bd_GetStringMsg.dtbgs_GInfo        = TRG(msg)->dtt_GInfo;
  766.                 bd->bd_GetStringMsg.dtbgs_SearchMethod = searchmethod;
  767.                 DoAsyncMethodA(obj,(Msg) &bd->bd_GetStringMsg,NULL);
  768.                 break;
  769.             }
  770.         }
  771.         break;
  772.     /* the real stringrequester method */
  773.     case DTBM_GETSTRING:
  774.         retval = getstring(cl,obj,(struct dtbGetString *) msg);
  775.         DB(("after getstring\n"));
  776.         break;
  777.     case DTBM_SEARCHNEXT:
  778.     case DTBM_SEARCHPREV:
  779.         {
  780.             UBYTE *ptr = bd->bd_Found;
  781.  
  782.             if(!ptr)
  783.                 ptr = bd->bd_Buffer;
  784.  
  785.             D(bug("search for : %s, len = %ld\n",SMSG(msg)->dtbs_Search,
  786.                                                              SMSG(msg)->dtbs_SearchLength));
  787.  
  788.             if(msg->MethodID == DTBM_SEARCHNEXT)
  789.                 ptr = searchstring(ptr + 2,
  790.                                          bd->bd_BufferEnd - ptr,
  791.                                          SMSG(msg)->dtbs_Search,
  792.                                          SMSG(msg)->dtbs_SearchLength,
  793.                                          1);
  794.             else
  795.             {
  796.                 ptr += (SMSG(msg)->dtbs_SearchLength - 2);
  797.                 if(ptr >= bd->bd_BufferEnd)
  798.                     ptr = bd->bd_BufferEnd - 1;
  799.  
  800.                 if((ptr = searchstring(ptr,
  801.                                               ptr - bd->bd_Buffer,
  802.                                               SMSG(msg)->dtbs_Search,
  803.                                               SMSG(msg)->dtbs_SearchLength,
  804.                                               -1)))
  805.                 {
  806.                     ptr -= SMSG(msg)->dtbs_SearchLength;
  807.                 }
  808.             }
  809.  
  810.             D(bug("found at : %lx\n",ptr));
  811.  
  812.             setAttrs(obj,SMSG(msg)->dtbs_GInfo,BDTA_Found,ptr,TAG_DONE);
  813.         }
  814.         break;
  815.     default:
  816.         retval = DoSuperMethodA(cl,obj,msg);
  817.     }
  818.  
  819.     return(retval);
  820. }
  821. /*FE*/
  822.  
  823. /*FS*/ ULONG getattr(Class *cl,Object *obj,struct opGet *msg)
  824. {
  825.     struct BinaryData *bd = INST_DATA(cl,obj);
  826.     ULONG *storage = msg->opg_Storage;
  827.  
  828.     switch(msg->opg_AttrID)
  829.     {
  830.     case DTA_TextFont:
  831.         *storage = (ULONG) bd->bd_Font;
  832.         break;
  833.     case DTA_TextAttr:
  834.         *storage = (ULONG) &bd->bd_TextAttr;
  835.         break;
  836.     case DTA_Methods:
  837.         *storage = (ULONG) methods;
  838.         break;
  839.     case BDTA_Buffer:
  840.         *storage = (ULONG) bd->bd_Buffer;
  841.         break;
  842.     case BDTA_BufferLen:
  843.         *storage = (ULONG) bd->bd_BufferLen;
  844.         break;
  845.     case BDTA_BytesPerLine:
  846.         *storage = (ULONG) bd->bd_BytesPerLine;
  847.         break;
  848.     case BDTA_DisplayHex:
  849.         *storage = (ULONG) bd->bd_DisplayHex;
  850.         break;
  851.     case BDTA_ShowASCII:
  852.         *storage = (ULONG) ((bd->bd_Flags & BDF_SHOWASCII) == BDF_SHOWASCII);
  853.         break;
  854.     case BDTA_DisplayWrap:
  855.         *storage = (ULONG) ((bd->bd_Flags & BDF_DISPLAYWRAP) == BDF_DISPLAYWRAP);
  856.         break;
  857.     default:
  858.         return(0);
  859.     }
  860.     return(1);
  861. }
  862. /*FE*/
  863. /*FS*/ ULONG setattrs(Class *cl,Object *obj,struct opSet *msg)
  864. {
  865.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  866.     struct BinaryData *bd = INST_DATA(cl,obj);
  867.  
  868.     struct TagItem *tstate = msg->ops_AttrList;
  869.     struct TagItem *tag;
  870.  
  871.     ULONG retval = 0;
  872.     ULONG tidata;
  873.  
  874.     while((tag = NextTagItem(&tstate)))
  875.     {
  876.         tidata = tag->ti_Data;
  877.  
  878.         DB(("tag : {0x%08lx,0x%08lx}\n",tag->ti_Tag,tidata));
  879.         retval++;
  880.         switch(tag->ti_Tag)
  881.         {
  882.         case DTA_TextAttr:
  883.             {
  884.                 struct TextFont *font;
  885.  
  886.                 if((font = OpenFont((struct TextAttr *) tidata)))
  887.                 {
  888.                     /* only use fixed width fonts */
  889.                     if(font->tf_Flags & FPF_PROPORTIONAL)
  890.                     {
  891.                         CloseFont(font);
  892.                         useDefaultFont(cb,bd);
  893.                     } else
  894.                     {
  895.                         bd->bd_TextAttr = *((struct TextAttr *) tidata);
  896.                         bd->bd_TextAttr.ta_Name = bd->bd_FontName;
  897.                         strcpy(bd->bd_FontName,((struct TextAttr *) tidata)->ta_Name);
  898.  
  899.                         if(bd->bd_Font)
  900.                             CloseFont(bd->bd_Font);
  901.  
  902.                         bd->bd_Font = font;
  903.                     }
  904.                     bd->bd_Flags |= BDF_NEEDLAYOUT;
  905.                 } else
  906.                     retval--;
  907.             }
  908.             break;
  909.         case BDTA_Buffer:
  910.             {
  911.                 ULONG len = GetTagData(BDTA_BufferLen,0,msg->ops_AttrList);
  912.  
  913.                 if(tidata && len)
  914.                 {
  915.                     if((bd->bd_Buffer) && (bd->bd_Flags & BDF_ALLOCATED))
  916.                         FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
  917.  
  918.                     bd->bd_Flags &= ~BDF_ALLOCATED;
  919.  
  920.                     bd->bd_Buffer    = (UBYTE *) tidata;
  921.                     bd->bd_BufferLen = len;
  922.                     bd->bd_BufferEnd = &bd->bd_Buffer[len];
  923.                     bd->bd_Flags |= BDF_NEEDLAYOUT;
  924.  
  925.                     retval++;
  926.                 } else
  927.                     retval--;
  928.             }
  929.             break;
  930.         case BDTA_BytesPerLine:
  931.             if(tidata != bd->bd_BytesPerLine)
  932.             {
  933.                 bd->bd_BytesPerLine = (UWORD) tidata;
  934.                 bd->bd_Flags |= BDF_NEEDLAYOUT;
  935.             } else
  936.                 retval--;
  937.             break;
  938.         case BDTA_DisplayHex:
  939.             if(tidata != bd->bd_DisplayHex)
  940.             {
  941.                 bd->bd_DisplayHex   = (UWORD) tidata;
  942.                 bd->bd_Flags |= BDF_NEEDLAYOUT;
  943.             } else
  944.                 retval--;
  945.             break;
  946.         case BDTA_ShowASCII:
  947.             if(tidata)
  948.                 bd->bd_Flags |= BDF_SHOWASCII;
  949.             else
  950.                 bd->bd_Flags &= ~BDF_SHOWASCII;
  951.             bd->bd_Flags |= BDF_NEEDLAYOUT;
  952.             break;
  953.         case BDTA_DisplayWrap:
  954.             if(tidata)
  955.                 bd->bd_Flags |= BDF_DISPLAYWRAP;
  956.             else
  957.                 bd->bd_Flags &= ~BDF_DISPLAYWRAP;
  958.             bd->bd_Flags |= BDF_NEEDLAYOUT;
  959.             break;
  960.         case BDTA_Found:
  961.             if(bd->bd_Found == (STRPTR) tidata)
  962.                 retval--;
  963.             else
  964.             {
  965.                 STRPTR ptr = (STRPTR) tidata;
  966.                 LONG total,vis,topy;
  967.  
  968.                 if(GetDTAttrs(obj,DTA_TotalVert  ,&total,
  969.                                         DTA_VisibleVert,&vis,TAG_END) == 2)
  970.                 {
  971.                     total -= vis;
  972.  
  973.                     topy = (ptr - bd->bd_Buffer) / bd->bd_BytesPerLine;
  974.                     if(topy > total)
  975.                         topy = total;
  976.                     else if(topy < 0)
  977.                         topy = 0;
  978.  
  979.                     D(bug("topy = %ld, ginfo : %lx\n",topy,msg->ops_GInfo));
  980.                     setSuperAttrs(cl,obj,msg->ops_GInfo,DTA_TopVert,topy,TAG_DONE);
  981.                     D(bug("after setSuper !\n"));
  982.  
  983.                     notifyAttrChanges(obj,msg->ops_GInfo,0,DTA_TopVert,topy,TAG_DONE);
  984.                     D(bug("after notify !\n"));
  985.                 }
  986.                 bd->bd_Found  = ptr;
  987.             }
  988.             break;
  989.         default:
  990.             retval--;
  991.         }
  992.     }
  993.  
  994.     DB(("setattrs retval : %ld\n",retval));
  995.     return(retval);
  996. }
  997. /*FE*/
  998.  
  999. /*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
  1000. {
  1001.     struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
  1002.     struct BinaryData *bd = INST_DATA(cl,obj);
  1003.  
  1004.     struct TextFont *font = bd->bd_Font;
  1005.  
  1006.     /* Attributes obtained from super-class */
  1007.     struct IBox *domain;
  1008.  
  1009.     ULONG retval = 0;
  1010.  
  1011.     ENTERING;
  1012.  
  1013.     /* Get all the attributes that we are going to need for a successful layout */
  1014.     if((GetDTAttrs(obj,DTA_Domain,      (ULONG) &domain,
  1015.                              TAG_DONE) == 1))
  1016.     {
  1017.         /* Lock the global object data so that nobody else can manipulate it */
  1018.         ObtainSemaphore (&(si->si_Lock));
  1019.  
  1020.         retval = si->si_TotVert;
  1021.  
  1022.         /* We only need to perform layout if we are doing word wrap, or this
  1023.          * is the initial layout call */
  1024.         if(gpl->gpl_Initial || (bd->bd_Flags & BDF_DISPLAYWRAP))
  1025.         {
  1026.             const UBYTE displayhexbytes[]   = {0,3,5,9};
  1027.             const UBYTE displayasciibytes[] = {1,1,2,4};
  1028.  
  1029.             WORD displayaddr = (bd->bd_BufferLen >= (1<<16)) ? 10 : 6;
  1030.             WORD numgroups;
  1031.             WORD bytesperline;
  1032.             WORD showascii = 0;
  1033.             LONG lines;
  1034.  
  1035.             D(bug("calc new layout values !\n"));
  1036.  
  1037.             if((bd->bd_Flags & BDF_SHOWASCII) || bd->bd_DisplayHex == BDTDH_NONE)
  1038.                 showascii = 1;
  1039.  
  1040.             numgroups    =
  1041.             bytesperline = bd->bd_BytesPerLine;
  1042.  
  1043.             if(bd->bd_DisplayHex > 0)
  1044.                 numgroups >>= (bd->bd_DisplayHex - 1);
  1045.  
  1046.             /* Note this wrap function doesn't work right with proportional fonts ! */
  1047.             if(bd->bd_Flags & BDF_DISPLAYWRAP)
  1048.             {
  1049.                 ULONG chars = domain->Width / bd->bd_Font->tf_XSize;
  1050.  
  1051.                 D(bug("object width : %ld\n",domain->Width));
  1052.                 D(bug("font width   : %ld\n",font->tf_XSize));
  1053.                 D(bug("chars        : %ld\n",chars));
  1054.  
  1055.                 if(chars > displayaddr + showascii)
  1056.                 {
  1057.                     bytesperline =
  1058.                     numgroups    = (chars - displayaddr - showascii) / (displayhexbytes[bd->bd_DisplayHex] +
  1059.                                                                                          ((showascii) ? displayasciibytes[bd->bd_DisplayHex] : 0));
  1060.  
  1061.                     if(numgroups < 1)
  1062.                         numgroups = 1;
  1063.                 } else
  1064.                     numgroups = 1;
  1065.  
  1066.                 if(bd->bd_DisplayHex > 0)
  1067.                     bytesperline = (numgroups) << (bd->bd_DisplayHex - 1);
  1068.             }
  1069.  
  1070.             if(bytesperline < 4)
  1071.             {
  1072.                 bytesperline  = 4;
  1073.                 numgroups     = 4 / displayasciibytes[bd->bd_DisplayHex];
  1074.             }
  1075.  
  1076.             lines = (bd->bd_BufferLen / bytesperline) + ((bd->bd_BufferLen % bytesperline) ? 1 : 0) - 1;
  1077.  
  1078.             bd->bd_LineBytes = displayaddr + numgroups * displayhexbytes[bd->bd_DisplayHex] +
  1079.                                      ((showascii) ? bytesperline : 0) + 1;
  1080.             bd->bd_NumGroups    = numgroups;
  1081.             bd->bd_BytesPerLine = bytesperline;
  1082.  
  1083.             if(bd->bd_LineBuffer && bd->bd_LineBytes > bd->bd_LineBufferLen)
  1084.             {
  1085.                 FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
  1086.                 bd->bd_LineBuffer = NULL;
  1087.             }
  1088.  
  1089.             if(!bd->bd_LineBuffer)
  1090.             {
  1091.                 bd->bd_LineBufferLen = bd->bd_LineBytes;
  1092.                 bd->bd_LineBuffer    = AllocMem(bd->bd_LineBufferLen,MEMF_ANY);
  1093.             }
  1094.  
  1095.             /* Compute the lines and columns type information */
  1096.             si->si_VertUnit  = font->tf_YSize;
  1097.             si->si_VisVert   = domain->Height / si->si_VertUnit;
  1098.             si->si_TotVert   = lines;
  1099.  
  1100.             si->si_HorizUnit = font->tf_XSize;
  1101.             si->si_VisHoriz  = domain->Width / font->tf_XSize;
  1102.             si->si_TotHoriz  = bd->bd_LineBytes;
  1103.  
  1104.             /* Release the global data lock */
  1105.             ReleaseSemaphore(&si->si_Lock);
  1106.  
  1107.             retval = lines;
  1108.  
  1109.             D(bug("after releasesem !\n"));
  1110.  
  1111.             if(gpl->gpl_Initial)
  1112.             {
  1113.                 struct RastPort *rp;
  1114.  
  1115.                 /* Get a pointer to the rastport */
  1116.                 if((rp = ObtainGIRPort (gpl->gpl_GInfo)))
  1117.                 {
  1118.                     struct gpRender gpr;
  1119.  
  1120.                     /* Force a redraw */
  1121.                     gpr.MethodID   = GM_RENDER;
  1122.                     gpr.gpr_GInfo  = gpl->gpl_GInfo;
  1123.                     gpr.gpr_RPort  = rp;
  1124.                     gpr.gpr_Redraw = GREDRAW_REDRAW;
  1125.                     DoMethodA (obj, (Msg) &gpr);
  1126.  
  1127.                     /* Release the temporary rastport */
  1128.                     ReleaseGIRPort (rp);
  1129.                 }
  1130.             }
  1131.         } else
  1132.             ReleaseSemaphore(&si->si_Lock);
  1133.  
  1134.         /* Not aborted, so tell the world of our newest attributes */
  1135.         notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
  1136.                                  GA_ID,                   G(obj)->GadgetID,
  1137.  
  1138.                                  DTA_VisibleVert,         domain->Height / font->tf_YSize,
  1139.                                  DTA_TotalVert,           retval,
  1140.                                  DTA_NominalVert,         font->tf_YSize * 25,
  1141.                                  DTA_VertUnit,            font->tf_YSize,
  1142.  
  1143.                                  DTA_VisibleHoriz,        domain->Width / font->tf_XSize,
  1144.                                  DTA_TotalHoriz,          bd->bd_LineBytes,
  1145.                                  DTA_NominalHoriz,        font->tf_XSize * 80,
  1146.                                  DTA_HorizUnit,           font->tf_XSize,
  1147.  
  1148.                                  DTA_Title,               bd->bd_Name,
  1149.                                  DTA_Busy,                FALSE,
  1150.                                  DTA_Sync,                TRUE,
  1151.                                  TAG_DONE);
  1152.  
  1153.     }
  1154.  
  1155.     LEAVING;
  1156.  
  1157.     return(retval);
  1158. }
  1159. /*FE*/
  1160.  
  1161. /*FS*/ LONG formatline(struct BinaryData *bd,STRPTR *start,STRPTR buf,ULONG num)
  1162. {
  1163.     STRPTR bptr = *start;
  1164.     STRPTR ptr  = bptr;
  1165.     STRPTR ptr1 = buf;
  1166.     UWORD numadd = (bd->bd_BufferLen > ((1<<16) - 1)) ? 10 : 6;
  1167.     UWORD grp;
  1168.  
  1169.     if(numadd == 10)
  1170.         sprintf(ptr1,"%08lx: ",num);
  1171.     else
  1172.         sprintf(ptr1,"%04lx: ",num);
  1173.     ptr1 += numadd;
  1174.  
  1175.     switch(bd->bd_DisplayHex)
  1176.     {
  1177.     case BDTDH_BYTE:
  1178.         for(grp = 0 ; grp < bd->bd_NumGroups && ptr < bd->bd_BufferEnd ; grp++)
  1179.         {
  1180.             sprintf(ptr1,"%02lx ",*ptr);
  1181.             ptr++;
  1182.             ptr1 += 3;
  1183.         }
  1184.  
  1185.         while(grp < bd->bd_NumGroups)
  1186.         {
  1187.             strcpy(ptr1,"   ");
  1188.             ptr1 += 3;
  1189.             ptr++;
  1190.             grp++;
  1191.         }
  1192.         break;
  1193.     case BDTDH_WORD:
  1194.         for(grp = 0 ; grp < bd->bd_NumGroups && ptr < bd->bd_BufferEnd ; grp++)
  1195.         {
  1196.             sprintf(ptr1,"%04lx ",*((UWORD *) ptr));
  1197.             ptr += sizeof(UWORD);
  1198.             ptr1 += 5;
  1199.         }
  1200.  
  1201.         while(grp < bd->bd_NumGroups)
  1202.         {
  1203.             strcpy(ptr1,"     ");
  1204.             ptr1 += 5;
  1205.             ptr += sizeof(UWORD);
  1206.             grp++;
  1207.         }
  1208.         break;
  1209.     case BDTDH_LONG:
  1210.         for(grp = 0 ; grp < bd->bd_NumGroups && ptr < bd->bd_BufferEnd ; grp++)
  1211.         {
  1212.             sprintf(ptr1,"%08lx ",*((ULONG *) ptr));
  1213.             ptr += sizeof(ULONG);
  1214.             ptr1 += 9;
  1215.         }
  1216.  
  1217.         while(grp < bd->bd_NumGroups)
  1218.         {
  1219.             strcpy(ptr1,"         ");
  1220.             ptr1 += 9;
  1221.             ptr += sizeof(ULONG);
  1222.             grp++;
  1223.         }
  1224.         break;
  1225.     default:
  1226.         ptr += bd->bd_BytesPerLine;
  1227.     }
  1228.  
  1229.     /* write ASCII string */
  1230.     if((bd->bd_Flags & BDF_SHOWASCII) ||
  1231.         (bd->bd_DisplayHex == BDTDH_NONE))
  1232.     {
  1233.         while(bptr < ptr && bptr < bd->bd_BufferEnd)
  1234.         {
  1235.             if(*bptr < 32)
  1236.                 *ptr1 = '.';
  1237.             else
  1238.                 *ptr1 = *bptr;
  1239.             ptr1++;
  1240.             bptr++;
  1241.         }
  1242.  
  1243.         while(bptr < ptr)
  1244.         {
  1245.             *ptr1++ = ' ';
  1246.             bptr++;
  1247.         }
  1248.     }
  1249.  
  1250.     *start = ptr;
  1251.  
  1252.     return((LONG) (ptr1 - buf));
  1253. }
  1254. /*FE*/
  1255.  
  1256. /*FS*/ ULONG getstring(Class *cl,Object *obj,struct dtbGetString *msg)
  1257. {
  1258.     struct BinaryData *bd = INST_DATA(cl,obj);
  1259.     struct GadgetInfo *ginfo = msg->dtbgs_GInfo;
  1260.     struct Library *ReqToolsBase;
  1261.     ULONG retval = 0;
  1262.  
  1263.     if((ReqToolsBase = OpenLibrary("reqtools.library",38)))
  1264.     {
  1265.         retval = rtGetString(bd->bd_InputString,sizeof(bd->bd_InputString),
  1266.                                     "Binary Datatype Search String",NULL,
  1267.                                     RT_Window     ,(ginfo) ? ginfo->gi_Window : NULL,
  1268.                                     RT_ReqPos     ,REQPOS_CENTERWIN,
  1269.                                     RT_LockWindow ,TRUE,
  1270.                                     TAG_DONE);
  1271.  
  1272.         CloseLibrary(ReqToolsBase);
  1273.  
  1274.         if(retval)
  1275.         {
  1276.             bd->bd_Found = bd->bd_Buffer;
  1277.             strcpy(bd->bd_SearchString,bd->bd_InputString);
  1278.             Forbid();
  1279.             DoMethod(obj,msg->dtbgs_SearchMethod,ginfo,bd->bd_SearchString,strlen(bd->bd_SearchString));
  1280.             Permit();
  1281.         }
  1282.     }
  1283.  
  1284.     return(retval);
  1285. }
  1286. /*FE*/
  1287. /*FS*/ UBYTE *searchstring(UBYTE *buf,LONG len,STRPTR string,LONG slen,LONG direction)
  1288. {
  1289.     LONG clen = slen;
  1290.     LONG elen = len - slen + 1;
  1291.     UBYTE *aptr = buf;
  1292.     UBYTE *ptr;
  1293.     UBYTE *sptr;
  1294.  
  1295.     if(direction == 1)
  1296.     {
  1297.         while(elen > 0 && clen > 0)
  1298.         {
  1299.             ptr  = aptr;
  1300.             sptr = string;
  1301.             clen = slen;
  1302.  
  1303.             while((*sptr++ == *ptr++) && clen > 0)
  1304.                 clen--;
  1305.  
  1306.             aptr++;
  1307.             elen--;
  1308.         }
  1309.         aptr--;
  1310.     } else if(direction == -1)
  1311.     {
  1312.         while(elen > 0 && clen > 0)
  1313.         {
  1314.             ptr  = aptr;
  1315.             sptr = string + slen - 1;
  1316.             clen = slen;
  1317.  
  1318.             while((*sptr-- == *ptr--) && clen > 0)
  1319.                 clen--;
  1320.  
  1321.             aptr--;
  1322.             elen--;
  1323.         }
  1324.         aptr++;
  1325.     }
  1326.  
  1327.     if(clen > 0)
  1328.         return(NULL);
  1329.  
  1330.     return(aptr);
  1331. }
  1332. /*FE*/
  1333.  
  1334.  
  1335.